Skip to content

Conversation

@DanielCChen
Copy link
Contributor

Fixes #143569.

@DanielCChen DanielCChen self-assigned this Oct 24, 2025
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir labels Oct 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 24, 2025

@llvm/pr-subscribers-flang-fir-hlfir

Author: Daniel Chen (DanielCChen)

Changes

Fixes #143569.


Full diff: https://github.com/llvm/llvm-project/pull/164999.diff

2 Files Affected:

  • (modified) flang/lib/Lower/Bridge.cpp (+4)
  • (modified) flang/test/Lower/forall-polymorphic.f90 (+41)
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index a516a44204cac..67d280cb3e128 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -4778,6 +4778,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
       mlir::Value shape = builder->genShape(loc, lbounds, extents);
       rhsBox = fir::ReboxOp::create(*builder, loc, lhsBoxType, rhsBox, shape,
                                     /*slice=*/mlir::Value{});
+    } else if (fir::isClassStarType(lhsBoxType) &&
+               !fir::ConvertOp::canBeConverted(rhsBoxType, lhsBoxType)) {
+      rhsBox = fir::ReboxOp::create(*builder, loc, lhsBoxType, rhsBox,
+                                    mlir::Value{}, mlir::Value{});
     }
     return rhsBox;
   }
diff --git a/flang/test/Lower/forall-polymorphic.f90 b/flang/test/Lower/forall-polymorphic.f90
index 2b7a51f9b549a..656b6ecf00628 100644
--- a/flang/test/Lower/forall-polymorphic.f90
+++ b/flang/test/Lower/forall-polymorphic.f90
@@ -1,6 +1,7 @@
 ! Test lower of FORALL polymorphic pointer assignment 
 ! RUN: bbc -emit-fir %s -o - | FileCheck %s
 
+
 !! Test when LHS is polymorphic and RHS is not polymorphic
 ! CHECK-LABEL: c.func @_QPforallpolymorphic
   subroutine forallPolymorphic()
@@ -46,6 +47,7 @@ subroutine forallPolymorphic()
 
   end subroutine forallPolymorphic
 
+
 !! Test when LHS is not polymorphic but RHS is polymorphic
 ! CHECK-LABEL: c.func @_QPforallpolymorphic2(
 ! CHECK-SAME: %arg0: !fir.ref<!fir.class<!fir.heap<!fir.array<?x!fir.type<_QFforallpolymorphic2Tdt{ptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QFforallpolymorphic2Tdt>>>>}>>>>> {fir.bindc_name = "tar1", fir.target}) {
@@ -87,3 +89,42 @@ subroutine forallPolymorphic2(Tar1)
 
   end subroutine forallPolymorphic2
 
+
+!! Test when LHS is unlimited polymorphic and RHS non-polymorphic intrinsic
+!! type target.
+! CHECK-LABEL: c.func @_QPforallpolymorphic3
+subroutine forallPolymorphic3()
+  TYPE :: DT
+    CLASS(*), POINTER    :: Ptr => NULL()
+  END TYPE
+
+  TYPE(DT) :: D1(10)
+  CHARACTER*1, TARGET :: TAR1(10)
+  INTEGER :: I
+
+  FORALL (I=1:10)
+    D1(I)%Ptr => Tar1(I)
+  END FORALL
+
+! CHECK: %[[V_7:[0-9]+]] = fir.alloca !fir.array<10x!fir.type<_QFforallpolymorphic3Tdt{ptr:!fir.class<!fir.ptr<none>>}>> {bindc_name = "d1", uniq_name = "_QFforallpolymorphic3Ed1"}
+! CHECK: %[[V_8:[0-9]+]] = fir.shape %c10 : (index) -> !fir.shape<1>
+! CHECK: %[[V_9:[0-9]+]] = fir.declare %[[V_7]](%[[V_8]]) {uniq_name = "_QFforallpolymorphic3Ed1"} : (!fir.ref<!fir.array<10x!fir.type<_QFforallpolymorphic3Tdt{ptr:!fir.class<!fir.ptr<none>>}>>>, !fir.shape<1>) -> !fir.ref<!fir.array<10x!fir.type<_QFforallpolymorphic3Tdt{ptr:!fir.class<!fir.ptr<none>>}>>>
+! CHECK: %[[V_16:[0-9]+]] = fir.alloca !fir.array<10x!fir.char<1>> {bindc_name = "tar1", fir.target, uniq_name = "_QFforallpolymorphic3Etar1"}
+! CHECK: %[[V_17:[0-9]+]] = fir.declare %[[V_16]](%[[V_8]]) typeparams %c1 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFforallpolymorphic3Etar1"} : (!fir.ref<!fir.array<10x!fir.char<1>>>, !fir.shape<1>, index) -> !fir.ref<!fir.array<10x!fir.char<1>>>
+! CHECK: %[[V_24:[0-9]+]] = fir.convert %c1_i32 : (i32) -> index
+! CHECK: %[[V_25:[0-9]+]] = fir.convert %c10_i32 : (i32) -> index
+! CHECK: fir.do_loop %arg0 = %[[V_24]] to %[[V_25]] step %c1
+! CHECK: {
+! CHECK: %[[V_26:[0-9]+]] = fir.convert %arg0 : (index) -> i32
+! CHECK: %[[V_27:[0-9]+]] = fir.convert %[[V_26]] : (i32) -> i64
+! CHECK: %[[V_28:[0-9]+]] = fir.array_coor %[[V_9]](%[[V_8]]) %[[V_27]] : (!fir.ref<!fir.array<10x!fir.type<_QFforallpolymorphic3Tdt{ptr:!fir.class<!fir.ptr<none>>}>>>, !fir.shape<1>, i64) -> !fir.ref<!fir.type<_QFforallpolymorphic3Tdt{ptr:!fir.class<!fir.ptr<none>>}>>
+! CHECK: %[[V_29:[0-9]+]] = fir.field_index ptr, !fir.type<_QFforallpolymorphic3Tdt{ptr:!fir.class<!fir.ptr<none>>}>
+! CHECK: %[[V_30:[0-9]+]] = fir.coordinate_of %[[V_28]], ptr : (!fir.ref<!fir.type<_QFforallpolymorphic3Tdt{ptr:!fir.class<!fir.ptr<none>>}>>) -> !fir.ref<!fir.class<!fir.ptr<none>>>
+! CHECK: %[[V_31:[0-9]+]] = fir.convert %[[V_26]] : (i32) -> i64
+! CHECK: %[[V_32:[0-9]+]] = fir.array_coor %[[V_17]](%[[V_8]]) %31 : (!fir.ref<!fir.array<10x!fir.char<1>>>, !fir.shape<1>, i64) -> !fir.ref<!fir.char<1>>
+! CHECK: %[[V_33:[0-9]+]] = fir.embox %[[V_32]] : (!fir.ref<!fir.char<1>>) -> !fir.box<!fir.ptr<!fir.char<1>>>
+! CHECK: %[[V_34:[0-9]+]] = fir.rebox %[[V_33]] : (!fir.box<!fir.ptr<!fir.char<1>>>) -> !fir.class<!fir.ptr<none>>
+! CHECK: fir.store %[[V_34]] to %[[V_30]] : !fir.ref<!fir.class<!fir.ptr<none>>>
+! CHECK: }
+
+end subroutine forallPolymorphic3

@DanielCChen DanielCChen marked this pull request as draft October 24, 2025 20:00
@DanielCChen
Copy link
Contributor Author

DanielCChen commented Oct 24, 2025

PR #164279 caused a couple of regressions in our downstream test run.
Using therebox in this PR instead of a permitted fir.convert fixed it.
I will investigate more to broaden the condition for rebox.

The code that was regressed.

    type base
        integer :: id
    end type

    type container
        class (base), pointer :: data => null()
        !type(base), pointer :: data => null()
    end type

    contains

    pure function makeData (i)
        type (base), pointer :: makeData
        integer*4, intent(in) :: i

        allocate (makeData)

        makeData = base(i)
    end function


end module

program fpAssgn016
use m
    type (container) :: co1(10)

   forall (i=1:10)
!   do i = 1,10                           !! work around
        co1(i)%data => makeData (i)
!   end do
    end forall

    do i =1, 10
        deallocate (co1(i)%data)
    end do

end

It executed successfully until PR #164279 was merged.
Flang now failed at the runtime with

> a.out

fatal Fortran runtime error(t.f:36): Invalid descriptor
Abort(coredump)

@DanielCChen
Copy link
Contributor Author

It seems the regression is a separate issue, and exposed by PR #164279. The rebox didn't fix the case when the pointer is not polymorphic.
I will put up this PR for review as planned and open a new issue for the "regression".

@DanielCChen DanielCChen marked this pull request as ready for review October 24, 2025 23:03
@DanielCChen
Copy link
Contributor Author

DanielCChen commented Oct 24, 2025

Issue #165055 is to track the failure of the non-polymorphic case at the above (not a regression).

… polymorphic and RHS is intrinsic type target.
@DanielCChen
Copy link
Contributor Author

It seems the regression is a separate issue, and exposed by PR #164279. The rebox didn't fix the case when the pointer is not polymorphic. I will put up this PR for review as planned and open a new issue for the "regression".

It turns out the "regression" with polymorphic pointer indeed requires a rebox.
I updated the patch for this PR to fix that.
Issue #165055 is tracking the non-polymorphic pointer assignment issue within FORALL. Note that it is not a regression.

…res to rebox the RHS to the LHS type iif LHS is polymorphic.
…so requires to rebox the RHS to the LHS type iif LHS is polymorphic."

This reverts commit 1582702.
@DanielCChen
Copy link
Contributor Author

I reverted the 2nd commit as the failure in issue #165055 will have a different fix.

Copy link
Contributor

@jeanPerier jeanPerier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM

@DanielCChen DanielCChen merged commit 63e45ef into llvm:main Oct 31, 2025
10 checks passed
@DanielCChen DanielCChen deleted the daniel_forall2 branch October 31, 2025 13:49
ckoparkar added a commit to ckoparkar/llvm-project that referenced this pull request Oct 31, 2025
* main:
  [SPIRV] Fix vector bitcast check in LegalizePointerCast (llvm#164997)
  [lldb][docs] Add troubleshooting section to scripting introduction
  [Sema] Fix parameter index checks on explicit object member functions (llvm#165586)
  To fix polymorphic pointer assignment in FORALL when LHS is unlimited polymorphic and RHS is intrinsic type target (llvm#164999)
  [CostModel][AArch64] Model cost of extract.last.active intrinsic (clastb) (llvm#165739)
  [MemProf] Select largest of matching contexts from profile (llvm#165338)
  [lldb][TypeSystem] Better support for _BitInt types (llvm#165689)
  [NVPTX] Move TMA G2S lowering to Tablegen (llvm#165710)
  [MLIR][NVVM] Extend NVVM mma ops to support fp64 (llvm#165380)
  [UTC] Support to test annotated IR (llvm#165419)
DEBADRIBASAK pushed a commit to DEBADRIBASAK/llvm-project that referenced this pull request Nov 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

flang:fir-hlfir flang Flang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[flang] Unlimited pointer assignment within FORALL caused FIR verification failure

3 participants